<template>
  <el-form
    :labelPosition="labelPosition"
    :model="form"
    :ref="ref"
    :rules="verify"
    class="demo-ruleForm"
    label-width="100px"
    v-loading="loading"
  >
    <template v-for="(item, index) in ruleForm">
      <el-form-item
        :key="index.toString() + 1"
        :label="item.label"
        :prop="item.model"
        v-if="item.el !== '' && item.el !== 'hide'"
      >
        <!--文本框-->
        <template v-if="item.el === 'input'">
          <el-input
            :placeholder="item.placeholder"
            :show-password="item.password"
            :style="item.style"
            v-if="item.type === 'number'"
            v-model.number="form[item.model]"
          ></el-input>
          <el-input
                  :placeholder="item.placeholder"
                  :show-password="item.password"
                  :style="item.style"
                  v-else
                  v-model="form[item.model]"
          ></el-input>
        </template>
        <!--多行文本框-->
        <!--<el-input  type="textarea" v-if="item.el === 'textarea'  " v-model="form[item.model]" :placeholder="item.placeholder" :style="item.style"></el-input>-->
        <!--下拉框-->
        <el-select
          :multiple="item.multiple"
          :placeholder="item.placeholder"
          :style="item.style"
          :validate-on-rule-change="false"
          v-if="item.el === 'select'"
          v-model="form[item.model]"
          @change="item.change"
        >
          <template
            v-for="(candidate_item, candidate_index) in item.candidate.values"
          >
            <el-option
              :key="index.toString() + 1 + candidate_index.toString() + 1"
              :label="candidate_item[item.candidate.label]"
              :value="candidate_item[item.candidate.value]"
            >
            </el-option>
          </template>
        </el-select>
        <!--单选开关-->
        <el-switch
          :active-value="item.activeValue"
          :inactive-value="item.inactiveValue"
          :style="item.style"
          :value="item.value"
          v-if="item.el === 'switch'"
          v-model="form[item.model]"
        ></el-switch>
        <!--多选复选框-->
        <el-checkbox-group
          :style="item.style"
          v-if="item.el === 'checkbox'"
          v-model="form[item.model]"
        >
          <template
            v-for="(candidate_item, candidate_index) in item.candidate.values"
          >
            <el-checkbox
              :key="index.toString() + 1 + candidate_index.toString() + 1"
              :label="candidate_item[item.candidate.value]"
              :name="item.model"
            >
              {{ candidate_item[item.candidate.label] }}
            </el-checkbox>
          </template>
        </el-checkbox-group>
        <!--单选按钮-->
        <el-radio-group
          :style="item.style"
          v-if="item.el === 'radio'"
          v-model="form[item.model]"
        >
          <template
            v-for="(candidate_item, candidate_index) in item.candidate.values"
          >
            <el-radio
              :key="index.toString() + 1 + candidate_index.toString() + 1"
              :label="candidate_item[item.candidate.label]"
              :name="item.model"
              :value="candidate_item[item.candidate.value]"
            >
            </el-radio>
          </template>
        </el-radio-group>
        <!--时间-->
        <template v-if="item.el === 'date'">
          <el-date-picker
            :placeholder="item.placeholder"
            :style="item.style"
            :type="item.dataType"
            v-if="dataType[item.dataType] === true"
            :value-format="item.format"
            v-model="dateModel[item.model].value"
          ></el-date-picker>
          <!-- <el-date-picker
            :placeholder="item.placeholder"
            :style="item.style"
            :value-format="item.format"
            type="date"
            v-else
            v-model="form[item.model]"
          ></el-date-picker>-->
        </template>

        <RHFile
          v-if="item.el === 'file'"
          :fileData="item.fileData"
          :ref="item.model + '_file'"
          :tableData="item.value"
        ></RHFile>
      </el-form-item>
    </template>
  </el-form>
</template>

<script>
import _ from "lodash";
import * as form_prop from "@/common/form/form_prop";
import RHFile from "@/common/file/index.vue";
export default {
  name: "form_index",
  components: {
    RHFile
  },
  data() {
    return {
      loading: true,
      btn: true,
      ref: "RHForm",
      ruleForm: [], //表单行
      rules: {}, //表单验证
      verify: {}, //表单验证
      form: {}, //表单参数
      dateModel: {}, //时间
      dataType: { datetimerange: true, daterange: true }, //时间
      fileModel: [], //文件
      fileSuccessInfo: {}, //文件
      pre: {
        status: false, // 发送请求
        url: null, // 获取数据地址
        param: {} // 参数
      },
      data: {}, // 数据 会覆盖默认值
      auldForm: {}, // 表单初始值
      initialForm: {
        // 预设属性值
        hide: {
          //隐藏
          el: "hide", //类型
          model: "hide", //返回表单键
          value: null //初始值
        },
        input: {
          //文本框
          el: "input", //类型
          label: "文本框", //标题
          password: false, //是否时密码框
          prop: {}, //验证
          placeholder: "", //提示信息
          model: "input", //返回表单键
          value: null, //初始值
          type: "string", // 文本框类型 默认string
          style: "" //样式
        },
        select: {
          //下拉框
          el: "select", //类型
          label: "select", //标题
          prop: {}, //验证
          placeholder: "", //提示信息
          model: "select", //返回表单的建
          value: null, //初始值
          candidate: {
            //候选参数
            url: "", //url 服务器获取候选参数
            param: {},
            label: "id", //显示值
            value: "name", //value
            values: [
              //候选参数
              //{"id":"1","name":"01"}
            ]
          },
          multiple: false, //false 单选 true 多选
          style: "", //样式
          change: function() {} //值改变事件
        },
        switch: {
          //选择按钮
          el: "switch", //类型
          label: "switch", //标题
          model: "switch", //返回表单键
          value: null, //初始值
          activeValue: "1", //选中值
          inactiveValue: "0", //未选中值
          style: "" //样式
        },
        checkbox: {
          //复选框
          el: "checkbox", //类型
          label: "checkbox", //标题
          prop: {}, //验证
          model: "checkbox", //返回表单键
          value: [], //初始值
          candidate: {
            //候选参数
            url: "", //url 服务器获取候选参数
            param: {},
            label: "name", //展示值
            value: "id", //value
            values: [
              //候选参数
              //{"id":"1","name":"01"}
            ]
          },
          //可选项目数量的限制
          // min:"",//最少
          // max:"",//最大
          style: "" //样式
        },
        radio: {
          //单选
          el: "radio", //类型
          label: "radio", //标题
          prop: {}, //验证
          model: "radio", //返回表单键
          value: null, //初始值
          candidate: {
            //候选参数
            url: "", //url 服务器获取候选参数
            param: {},
            label: "id", //展示值
            value: "name", //value
            values: [
              //候选参数
              //{"id":"1","name":"01"}
            ]
          },
          style: "" //样式
        },
        date: {
          //日期
          el: "date", //类型
          label: "date", //标题
          dataType: "date",
          format: "yyyy-MM-dd HH:mm:sss",
          prop: {}, //验证
          placeholder: "", //提示信息
          model: "date", //返回表单键
          startModel: null,
          startValue: null,
          endModule: null,
          endValue: null,
          value: null, //初始值
          style: "" //样式
        },
        //文件
        file: {
          el: "file", //类型
          label: "file", //标题
          prop: {}, //验证
          placeholder: "", //提示信息
          model: "file", //返回表单键
          value: null, //初始值
          fileData: {
            key: null,
            imgBtn: {
              show: false,
              value: "选择图片"
            },
            fileBtn: {
              show: false,
              value: "选择文件"
            },
            folderBtn: {
              show: false,
              value: "选择文件夹"
            },
            success: this.fileSuccess
          }
        }
      }
    };
  },
  methods: {
    fileSuccess(message, rootFile, file, chunk, key) {
      /* let entity = JSON.parse(message).entity;
      if (!this.fileSuccessInfo[key]) {
        this.fileSuccessInfo[key] = {};
      }
      this.fileSuccessInfo[key][entity.fileId + file.uniqueIdentifier] = {
        name: file.name,
        fileType: file.fileType,
        relativePath: file.relativePath,
        size: file.size,
        state: file.state,
        stateProgress: file.stateProgress,
        status: 1,
        uniqueIdentifier: file.uniqueIdentifier,
        fileId: entity.fileId,
        md5: entity.md5,
        totalSize: entity.totalSize,
        url: entity.url
      };*/
    },
    columnDispose(item, prop, model) {
      if (item.el === "input") {
        //文本框
        //效验
        if (!_.isArray(prop)) {
          this.$set(this.rules, model, form_prop.input(prop, item.label));
        }
        if (_.isEmpty(item.placeholder)) {
          item.placeholder = "请输入" + item.label;
        }
      } else if (item.el === "select") {
        //下拉框
        //效验
        if (!_.isArray(prop)) {
          this.$set(this.rules, model, form_prop.select(prop, item.label));
        }
        if (_.isEmpty(item.placeholder)) {
          item.placeholder = "请选择" + item.label;
        }
      } else if (item.el === "checkbox") {
        //多选复选框
        //效验
        if (!_.isArray(prop)) {
          this.$set(this.rules, model, form_prop.checkbox(prop, item.label));
        }
      } else if (item.el === "radio") {
        //单选按钮
        //效验
        if (!_.isArray(prop)) {
          this.$set(this.rules, model, form_prop.radio(prop, item.label));
        }
      } else if (item.el === "date") {
        //日期
        //效验
        if (!_.isArray(prop)) {
          this.$set(this.rules, model, form_prop.date(prop, item.label));
        }
      }
    },
    initialize(item) {
      item = _.defaultsDeep(item, this.initialForm[item.el]);
      if (item.el === "select" && item.multiple && item.value === null) {
        item.value = [];
      }
      if (item.el === "file") {
        if (item.value === null) {
          item.value = [];
        }
        item.fileData.key = item.model;
        this.fileModel.push(item.model);
      }
      const model = item.model; //属性值
      let value = item.value; //初始值
      const prop = item.prop || {}; //效验
      if (!_.isNil(model)) {
        if (item.el === "date" && this.dataType[item.dataType] === true) {
          let value = [];
          if (!_.isNil(this.data[item.endModule])) {
            //是否有值
            this.$set(this.form, item.endModule, this.data[item.endModule]);
            /*if(!_.isNull(this.data[item.endModule])){
              value[1] = this.data[item.endModule];
            }*/
          } else {
            //是否有值
            this.$set(this.form, item.endModule, item.endValue);
            if (!_.isNull(item.endValue)) {
              value[1] = item.endValue;
            }
          }
          if (!_.isNil(this.data[item.startModel])) {
            //时间范围选择器
            this.$set(this.form, item.startModel, this.data[item.startModel]);
            if (!_.isNull(this.data[item.startModel])) {
              value[0] = this.data[item.startModel];
            }
          } else {
            //是否有值
            this.$set(this.form, item.startModel, item.startValue);
            if (!_.isNull(item.startValue)) {
              value[0] = item.startValue;
            }
          }
          //效验 开始日期
          if (_.isArray(prop)) {
            this.$set(this.rules, item.startModel, prop);
          }
          this.columnDispose(item, prop, item.startModel);
          //效验 结束日期
          if (_.isArray(prop)) {
            this.$set(this.rules, item.endModule, prop);
          }
          this.columnDispose(item, prop, item.endModule);

          this.$set(this.dateModel, model, {
            model: model,
            startModel: item.startModel,
            endModule: item.endModule,
            value: value
          });
        } else if (item.el === "file") {
          //文件
          if (!_.isNil(this.data[model])) {
            //是否有数据
            let fileValue = this.data[model];
            item.value = JSON.parse(fileValue);
            //是否有值
            this.$set(this.form, model, JSON.parse(fileValue));
          }
        } else {
          if (!_.isNil(this.data[model])) {
            //是否有值
            this.$set(this.form, model, this.data[model]);
          } else {
            //是否有值
            this.$set(this.form, model, value);
          }
          //通过url读取数据
          if (_.has(item, "candidate")) {
            //检查是否是多个候选值
            //判断url是否是null
            if (!_.isEmpty(item.candidate.url)) {
              form_prop
                .getCandidateValues(item.candidate.url, item.candidate.param)
                .then(response => {
                  item.candidate.values = response.data;
                  //手动更新数据
                  this.$forceUpdate();
                });
            }
          }
          //效验
          if (_.isArray(prop)) {
            this.$set(this.rules, model, prop);
          }
          this.columnDispose(item, prop, model);
        }
      }
    },
    //表单初始化
    refresh() {
      if (!_.isNil(this.RHForm)) {
        for (let index = 0; index < this.RHForm.length; index++) {
          let item = this.RHForm[index];
          this.initialize(item);
        }
      }
      this.verify = this.rules;
      this.auldForm = _.clone(this.form);
      this.ruleForm = _.defaultsDeep(this.RHForm, this.ruleForm);
      this.loading = false;
    },
    //表单效验
    RHFormValidate(fun) {
      for (let i = 0; i < this.fileModel.length; i++) {
        let fileRef = this.fileModel[i] + "_file";
        let tableData = this.$refs[fileRef][0].table.data;
        this.form[this.fileModel[i]] = [];
        for (let j = 0; j < tableData.length; j++) {
          if (tableData[j].fileId == null) {
            this.$message.error("请等待文件上传完毕！");
            return;
          }
          if (tableData[j].status === 2) {
            this.$message.error("有文件上传失败！");
            return;
          }
          if (tableData[j].status === 0) {
            this.$message.error("请等待文件上传完毕！");
            return;
          }
          let data = tableData[j];
          let item = {
            name: data.name,
            fileType: data.fileType,
            relativePath: data.relativePath,
            size: data.size,
            state: data.state,
            stateProgress: data.stateProgress,
            status: 1,
            uniqueIdentifier: data.uniqueIdentifier,
            fileId: data.fileId,
            md5: data.md5,
            fileSize: data.fileSize,
            url: data.url
          };
          console.log(item);
          this.form[this.fileModel[i]].push(item);
        }
      }
      //时间范围选择
      const _this = this;
      _.forEach(this.dateModel, function(value, key) {
        _this.form[value.startModel] = value.value[0];
        _this.form[value.endModule] = value.value[1];
      });
      this.$refs[this.ref].validate(valid => {
        fun(valid, this.form);
      });
    },
    resetForm() {
      this.form = _.clone(this.auldForm);
      this.$refs[this.ref].resetFields();
    },
    //表单赋值
    formInitialize(param) {
      this.$nextTick(() => {
        const key = _.keys(this.form);
        key.forEach((item, index) => {
          this.form[item] = param[item];
        });
      });
    },
    /**
     * 获取form
     */
    getForm(key) {
      if (_.isEmpty(key)) {
        return this.form;
      } else {
        return this.form[key];
      }
    }
  },
  mounted() {
    this.pre = _.defaultsDeep(this.RHPre, this.pre);
    if (this.pre.status && !_.isEmpty(this.pre.url)) {
      this.pre.status = false;
      form_prop
        .getCandidateValues(this.pre.url, this.pre.param)
        .then(response => {
          this.data = response.entity;
          this.refresh();
        });
    } else {
      this.refresh();
    }
  },
  props: {
    RHForm: {
      type: Array
    },
    RHPre: {
      type: Object
    },
    success: {
      type: Function,
      default: function() {}
    },
    error: {
      type: Function,
      default: function() {}
    },
    labelPosition: {
      type: String,
      default: "top"
    }
  }
};
</script>

<style scoped></style>
